home *** CD-ROM | disk | FTP | other *** search
/ The Macintosh Bible Guide to Games / GameGuideCd.bin / Shareware / Miscellaneous / tads22 folder / TADSVER.MAC < prev   
Text File  |  1994-09-24  |  94KB  |  2,042 lines

  1. This file contains a list of changes that have been made to TADS
  2. since the version 2.1.0 release.  Most of the changes are fixes to
  3. bugs, so they don't change the documented behavior, but a few, as
  4. explained below, add new functionality to TADS.  Releases are
  5. listed with the most recent release first; each release incorporates
  6. all new features and bug fixes of each prior release unless
  7. otherwise stated.
  8.  
  9. Note:  changes from version 2.0 up to 2.1.0 are not included in
  10. this file in order to keep its size under control.  The revisions
  11. from 2.0 through 2.1.0 are available in the file TADSV200.DOS, which
  12. can be found on the High Energy BBS.
  13.  
  14.  
  15. 2.2.0  ??/??/??  new features, enhancements, bug fixes
  16.  
  17.   - TADS now has support for reading and writing files.  This new
  18.     feature is intended to let you save information independently
  19.     of the game-saving mechanism, which allows you to transfer
  20.     information between sessions of a game, or even between two
  21.     different games.  The TADS file operations are not designed
  22.     as general-purpose file system operations; in particular,
  23.     these new functions don't have any provisions for creating or
  24.     reading formatted files, or for exchanging information with
  25.     programs other than TADS games.
  26.  
  27.     To open a file, use the fopen() function.  This function takes
  28.     two arguments:  a single-quoted string giving the name of the
  29.     file to open, using local file system conventions, and a "mode."
  30.     (For  maximum portability, you should avoid using volume names,
  31.     directories, folders, or other path information in filenames.)
  32.     The mode argument is one of these single-quoted string values:
  33.  
  34.         r    open file for reading; file must already exist
  35.         r+   open file for reading and writing; the file is
  36.              created if it doesn't already exist
  37.         w    create a new file for writing; the file is deleted
  38.              if it already exists
  39.         w+   create a new file for reading and writing; the file
  40.              is deleted if it already exists
  41.  
  42.     The return value of fopen() is a "file handle"; this is simply
  43.     a number that you you to perform subsequent operations on the
  44.     file.   For example, this opens a new file called TEST.OUT for
  45.     writing:
  46.  
  47.         fnum := fopen('test.out', 'w');
  48.  
  49.     To close an open file, use fclose():
  50.  
  51.         fclose(fnum);
  52.  
  53.     Note that the TADS runtime allows only a limited number of
  54.     files (currently 10) to be open simultaneously, so you should
  55.     close a file when you're done with it.
  56.  
  57.     To write to a file, use fwrite().  This function takes a file
  58.     handle, and a value to write; the value can be a string, a number,
  59.     or true.  The value can't be nil (this is because the fread() function
  60.     returns nil to indicate failure; if you could write nil to a file,
  61.     there would be no way to distinguish reading a valid nil from an
  62.     error condition).  fwrite() stores the value, along with information
  63.     on its type.
  64.  
  65.     The fwrite() function returns nil on success, true on failure.  If
  66.     the function returns true, it usually means that the disk is full.
  67.  
  68.        if (fwrite(fnum, 'string value!')
  69.            or fwrite(fnum, 123))
  70.            "Error writing file!";
  71.  
  72.     If the file is open for reading, you can read from the file with
  73.     the fread() function.  This function takes a file handle, and it
  74.     returns a value it reads from the file.  The value returned is
  75.     of the same type as the value originally written at this position
  76.     in the file with fwrite().  If this function returns nil, it
  77.     indicates that an error occurred; this usually means that no more
  78.     information is in the file (you've read past the end of the file).
  79.  
  80.        res := fread(fnum);
  81.        say(res);
  82.  
  83.     You can get the current byte position in the file with the ftell()
  84.     function:
  85.  
  86.        "The current seek position is << ftell(fnum) >>. ";
  87.  
  88.     The ftell() function returns a number giving the byte position
  89.     that will be read or written by the next file operation.
  90.  
  91.     You can set the file position with fseek() and fseekeof().  The
  92.     fseek() function moves the file position to a particular byte
  93.     position, relative to the beginning of the file.  For example,
  94.     this seeks to the very beginning of a file:
  95.  
  96.        fseek(fnum, 0);
  97.  
  98.     The fseekeof() function positions the file at its end:
  99.  
  100.        fseekeof(fnum);
  101.  
  102.     Note that you must be careful with fseek().  You should only seek
  103.     to positions that you obtained with the ftell() function; other
  104.     positions may be in the middle of a string or a number in the
  105.     file, so seeking to an arbitrary location and writing could
  106.     render the file unusable by partially overwriting existing data.
  107.  
  108.  
  109.   - TADS now allows you to create and delete objects dynamically
  110.     at run-time.  This is done through two new operators:  "new"
  111.     and "delete".
  112.  
  113.     To create a new object, use this syntax:
  114.  
  115.         x := new bookItem;
  116.  
  117.     This dynamically creates a new object whose superclass is bookItem.
  118.     When this statement is executed, the runtime creates a new object,
  119.     assigns its superclass to be bookItem, and executes the "construct"
  120.     method in the new object; this method can perform any creation-time
  121.     setup that's desired.  The default thing.construct in adv.t simply
  122.     moves the new object into its location -- this is necessary so that
  123.     the "contents" list of the location is updated to include the new
  124.     object.
  125.  
  126.     A new object inherits all of the vocabulary of its superclass.
  127.  
  128.     To destroy an object you have created, use this syntax:
  129.  
  130.         delete x;
  131.  
  132.     This first calls the "destruct" method of the object to notify it
  133.     that it is about to be deleted, then destroys the object.  Further
  134.     references to the object are illegal, since its memory has been
  135.     released (and thus may be given to another object).  The default
  136.     thing.destruct in adv.t moves the object into nil, which removes it
  137.     from its container's "contents" list -- this is necessary so that
  138.     the reference to the object in that list is removed.
  139.  
  140.     Only objects created with "new" can be destroyed with "delete".
  141.     Objects that are defined statically in your game's source file
  142.     cannot be deleted at run-time.
  143.  
  144.     Object creation and deletion works correctly with the UNDO
  145.     mechanism.  If the player uses UNDO after a move that created an
  146.     object, the object will be destroyed; likewise, if a player uses
  147.     UNDO after a turn that deletes an object, the object will be
  148.     re-created with the same property values it had prior to deletion.
  149.     Similarly, dynamically-created objects are preserved across SAVE
  150.     and RESTORE operations.
  151.  
  152.     Note that TADS does not perform any garbage collection on
  153.     dynamically-created objects.  The system is not capable of
  154.     determining whether an object is accessible or not.  Hence, if
  155.     you lose track of any objects you create with "new", they will
  156.     remain in memory forever -- they will even be saved along with
  157.     saved games and restored when the games are restored.  You must
  158.     be careful to keep track of all objects you create to avoid
  159.     filling all available memory (and the swap file) with unreachable
  160.     objects.
  161.  
  162.   - It is now possible to dynamically add to and delete from the
  163.     vocabulary words of an object.  You can also get the vocabulary
  164.     words of an object at run-time.
  165.  
  166.     To add to an object's vocabulary, use the new "addword" built-in
  167.     function.  This function takes three arguments:  an object, a
  168.     vocabulary property pointer, and a word to add.  For example,
  169.     to add 'red' as an adjective to the object myBook, you would
  170.     do this:
  171.  
  172.         addword(myBook, &adjective, 'red');
  173.  
  174.     To delete the same word, you would write a similar call to the
  175.     new built-in function "delword":
  176.  
  177.         delword(myBook, &adjective, 'red');
  178.  
  179.     You can add to and delete from the words of any object, including
  180.     both static objects (explicitly defined in your source code) and
  181.     dynamically-created objects (created with the "new" operator).
  182.  
  183.     Changes made by addword and delword are tracked correctly by the
  184.     UNDO mechanism, and are saved and restored along with saved games.
  185.  
  186.     To get the words belonging to an object, use the new "getwords"
  187.     built-in function.  This function takes two arguments:  an object,
  188.     and a property pointer; it returns a list of (single-quoted)
  189.     strings, which are the vocabulary words for the object.  For
  190.     example, assume we define myBook as follows:
  191.  
  192.         myBook:  item
  193.             sdesc = "small red book"
  194.             adjective = 'small' 'red' 'tiny'
  195.             noun = 'book'
  196.             location = room2
  197.         ;
  198.  
  199.     Also assume we haven't made any calls to addword() or delword() for
  200.     myBook.  In this case,
  201.  
  202.         getwords(myBook, &adjective)
  203.  
  204.     would return this list:
  205.  
  206.         ['small' 'red' 'tiny']
  207.  
  208.     Note that the order of the words in the list is not predictable,
  209.     so you shouldn't expect the words to be in the same order as they
  210.     were when you defined them in the source file, or in the same
  211.     order as they were added with addword().
  212.  
  213.   - We've added a new function that lets you get information on a verb.
  214.     The new function is verbinfo().  This function lets you get the
  215.     verification and action properties for a verb.  The new function
  216.     takes one or two arguments:  the first is the deepverb object whose
  217.     information you want to retrieve; the optional second argument is
  218.     a preposition object.  If you call verbinfo() with only the verb
  219.     argument, it returns the verification and action properties that
  220.     are defined with the doAction definition for the verb.  If you
  221.     also include the preposition argument, it returns the properties
  222.     that are defined with the ioAction definition for that preposition.
  223.  
  224.     The value returned by this function is a list.  If you call verbinfo()
  225.     with only the deepverb argument, the list has two elements:
  226.  
  227.       [1]   direct object verification property pointer (verDoXxxx)
  228.       [2]   direct object action property pointer (doXxxx)
  229.  
  230.     If you call verbinfo() with both the verb and preposition arguments,
  231.     the return value is a list with four elements:
  232.  
  233.       [1]   direct object verification property pointer (verDoXxxx)
  234.       [2]   indirect object verification property pointer (verIoXxxx)
  235.       [3]   indirect object action property pointer (ioXxxx)
  236.       [4]   true if ioAction has [disambigDobjFirst] flag, nil otherwise
  237.  
  238.     In either case, if no matching doAction or ioAction definition
  239.     exists for the verb, this function returns nil.
  240.  
  241.     Note that it is possible that additional flags (similar to
  242.     disambigDobjFirst) may be added in the future; the returned list
  243.     may be expanded to include information on any such added flags.
  244.     So, for compatibility with future versions, we recommend that you
  245.     don't write conditional code based on the length of the list.
  246.     The lists will never shrink, but they may expand.
  247.  
  248.     For the removeVerb object defined in adv.t, you would get these
  249.     results:
  250.  
  251.       verbinfo(removeVerb)
  252.         = [&verDoUnwear &doUnwear]
  253.  
  254.       verbinfo(removeVerb, fromPrep)
  255.         = [&verDoRemoveFrom &verIoRemoveFrom &ioRemoveFrom nil]
  256.  
  257.   - The ability to create new objects at run-time leads to some
  258.     interesting problems involving indistinguishable objects.  Although
  259.     you should generally use addword (see below) to make your newly-created
  260.     objects distinguishable from one another, this will not always be
  261.     desirable; for example, if you create new gold pieces that serve
  262.     as currency, you will probably not want them to be uniquely named.
  263.  
  264.     To support indistinguishable objects, especially those created
  265.     dynamically at run-time, the system now has a property that you
  266.     can set to indicate to the parser that an object does not need to
  267.     be distinguished from others of the same class.  The new property
  268.     is "isEquivalent".  When isEquivalent returns true for an object,
  269.     all other objects with the same immediate superclass are considered
  270.     interchangeable by the parser.  When a player uses one of these
  271.     objects in a command, the parser will simply pick one arbitrarily
  272.     and use it, without asking the player which one.
  273.  
  274.     If a player uses a noun that is ambiguous with multiple equivalent
  275.     items and one or more other items, the parser will need to
  276.     disambiguate the objects as usual.  In such cases, the parser's
  277.     question will list the distinguishable items only once.  For
  278.     example, assume we have five gold coins that are all equivalent
  279.     (in other words, they all have isEquivalent set to true, and they
  280.     all are immediate subclasses of the same class).  Assume further
  281.     that a silver coin and a bronze coin are also present in the room.
  282.  
  283.        Treasure Room
  284.            You see a bronze coin, five gold coins, and a silver
  285.        coin here.
  286.  
  287.        >get coin
  288.        Which coin do you mean, the bronze coin, a gold coin, or
  289.        the silver coin?
  290.  
  291.     Note that the objects which appear only once are listed with "the"
  292.     (using the thedesc property), while the indistinguishable objects
  293.     are listed only once, with "a" (using the adesc property).
  294.  
  295.   - The new property pluraldesc has been added to thing in adv.t.
  296.     The definition in thing simply adds an "s" to the end of the
  297.     sdesc property.  This new property is used by listcont(obj)
  298.     when multiple equivalent objects are present in a list; see the
  299.     information on the changes to listcont(obj) for details.
  300.  
  301.   - The adv.t functions listcont(obj) and itemcnt(list) have been
  302.     changed to support indistinguishable objects.  To support this
  303.     new functionality, the new functions isIndistinguishable(obj1, obj2)
  304.     and sayPrefixCount(cnt), and the new property pluraldesc, have
  305.     been added to adv.t.
  306.  
  307.     isIndistinguishable(obj1, obj2) returns true if the two objects
  308.     obj1 and obj2 are equivalent for the purposes of listing.  The
  309.     two objects are considered equivalent if both have the same
  310.     first superclass (the return value of the new built-in function
  311.     firstsc(obj)), either they are both being worn or neither is
  312.     worn, and either both are lit lightsources or neither is.  This
  313.     function doesn't test the isEquivalent property of either object,
  314.     since it's assumed that it will only be called if an object has
  315.     already been found whose isEquivalent property is set.
  316.  
  317.     sayPrefixCount(cnt) displays a number.  If the parameter cnt is
  318.     a small number (from one to twenty), the spelled-out number will
  319.     be displayed (for example, "five" will displayed if cnt = 5).  If
  320.     the count is larger, the number will be displayed as digits ("35"
  321.     will be displayed if cnt = 35).  This function is used by
  322.     listcont(obj) to show the number of equivalent items when more
  323.     than one equivalent item is being listed.
  324.  
  325.     itemcnt(list) now returns the number of distinguishable items in
  326.     the list that are to be listed.  For each item in the list whose
  327.     isEquivalent property is true, itemcnt(list) checks each other
  328.     item in the list, and counts each set of equivalent items only once.
  329.     Hence, if a list consists entirely of equivalent items, itemcnt(list)
  330.     will return at most 1 (it will return 0 if none of the items are
  331.     listable).
  332.  
  333.     listcont(obj) will list each set of indistinguishable items in the
  334.     contents list only once, and will show the number of each such item.
  335.     To display the number, the new function sayPrefixCount(cnt) is
  336.     used.  For example, if a room contains a silver coin, a bronze coin,
  337.     and five gold coins (all with the isListed property set to true),
  338.     listcont(room) will display this:
  339.  
  340.        a silver coin, a bronze coin, and five gold coins
  341.  
  342.   - A new built-in function has been added to make it possible to
  343.     implement the functionality of the new listcont method.  The new
  344.     function, firstsc(obj), returns the first immediate superclass of
  345.     the given object (or nil if the object has no superclass).  This
  346.     function, along with the isEquivalent property, can be used to
  347.     determine if two objects should be considered indistinguishable.
  348.  
  349.   - A new special word has been added:  ANY, which is equivalent to
  350.     EITHER.  These words are at the end of the original specialWords
  351.     list; for compatibility with past versions, a specialWords list
  352.     that omits this position is still legal, and indicates that the
  353.     default ('any' = 'either') should be used for this slot.
  354.  
  355.     This special word slot is used by the parser during disambiguation.
  356.     Whenever the parser asks the player to choose an object from a list
  357.     of ambiguous objects, it will accept ANY:
  358.  
  359.         >take coin
  360.         Which coin do you mean, the silver coin, the bronze coin, or
  361.         the gold coin?
  362.  
  363.         >any
  364.         silver coin:  Taken.
  365.  
  366.     When ANY is used in these cases, the parser will simply pick one
  367.     of the objects arbitrarily.  Note that it displays the chosen
  368.     object in the same manner as it would if multiple objects were
  369.     being used.
  370.  
  371.     In addition, the parser will accept noun phrases that start with
  372.     ANY to indicate that any object matching the given noun phrase is
  373.     acceptable; the parser will choose one of the objects arbitrarily
  374.     in these cases.  For example:
  375.  
  376.         >take any coin
  377.         silver coin:  Taken.
  378.  
  379.         >look at any of the coins
  380.         bronze coin:  It's a valuable 1964 Tadsmid, worth over
  381.         .0004 cents on today's scrap bronze market.
  382.  
  383.     The player can also specify the number of items to take.  When
  384.     a number of items is specified, it must be applied to a plural
  385.     noun phrase, and it means the same thing as "any," except that
  386.     the parser (arbitrarily) chooses the given number of items rather
  387.     than just one.  For example:
  388.  
  389.     >look at 3 coins
  390.     >look at any 3 coins
  391.     >look at 3 of the coins
  392.     >look at any 3 of the coins
  393.  
  394.     As a special case, a count of "1" can be used with a singular
  395.     noun phrase.  It means the same thing as "any."
  396.  
  397.         >look at 1 coin
  398.  
  399.   - A new convenience feature, similar to doSynonym and ioSynonym but
  400.     somewhat easier to use, has been added.  You can now specify that
  401.     a method in one object should instead be sent to another object.
  402.     An example:
  403.  
  404.         desk: fixeditem
  405.             noun = 'desk'
  406.             sdesc = "desk"
  407.             location = office
  408.             doOpen -> deskDrawer
  409.             doClose -> deskDrawer
  410.         ;
  411.  
  412.     This specifies that doOpen, verDoOpen, doClose, and verDoClose
  413.     calls should be sent to the deskDrawer object when received by
  414.     the desk.  Note that this should only be used for standard verb
  415.     handler methods, because it redirects both the method indicated
  416.     and its verXoVerb equivalent.
  417.  
  418.   - The parser calls a new method, multisdesc, when displaying the
  419.     name of an object that's part of a list of objects.  Previously,
  420.     the parser simply used sdesc in these cases.  The default adv.t
  421.     definition of thing.multisdesc simply calls the object's sdesc.
  422.     This new method is intended to allow you greater control over
  423.     the display in situations like this:
  424.  
  425.       >get all
  426.       book:  Taken.
  427.       rug:  That's much too heavy to carry.
  428.  
  429.     The object names listed before the colons are now displayed
  430.     with multisdesc.
  431.  
  432.     For compatibility with old games, if an object being listed does
  433.     not define or inherit a multisdesc property, its sdesc is used
  434.     instead.  This ensures that games compiled with previous versions
  435.     of adv.t will continue working properly.
  436.  
  437.   - A new user-defined function that the parser calls has been added.
  438.     This new function is called preparseCmd(), and is similar to
  439.     preparse().  Whereas preparse() is called once for an entire
  440.     command line, and is called with the original, unfiltered text
  441.     of the player's command line, preparseCmd() is called separately
  442.     for each command on a command line if more then one command is
  443.     entered.  Furthermore, preparseCmd() is called after the command
  444.     has been "tokenized" (broken into individual words).  Whereas the
  445.     argument to preparse() is a string with the entire command line,
  446.     the argument to preparseCmd() is a list, each entry of which is
  447.     a (single-quoted) string giving an individual word.  Using the new
  448.     function, you can exert much greater control over how a command
  449.     is parsed, including rewriting a command entirely.
  450.  
  451.     preparseCmd() is called immediately before Me.roomCheck() is called
  452.     for the command.  This call is made prior to any disambiguation or
  453.     object defaulting.
  454.  
  455.     If preparseCmd() returns nil, the command is abandoned (but no
  456.     error message is displayed), and no fuses or daemons are run.  If
  457.     the function returns true, the command proceeds as normal.  Any
  458.     remaining commands on the same line are executed regardless of the
  459.     return value from preparseCmd().  (If you need to cancel the entire
  460.     rest of the command line, one approach would be to set a property
  461.     in the global object to indicate to preparseCmd() that all commands
  462.     are to be ignored; preparseCmd() would always check this property
  463.     before doing anything else, and return nil if it were set.  You
  464.     could clear this property in preparse() so that commands always
  465.     start off enabled.)
  466.  
  467.     In addition, preparseCmd() can return a list of (single-quoted)
  468.     strings, in which case the parser starts over parsing the list
  469.     instead of the original command.  The list is limited to a maximum
  470.     of 128 characters, with one additional character of overhead per
  471.     word -- in other words, you can't make the new command longer
  472.     than the original command, which is limited to the same maximum
  473.     when entered by the player in the first place.  However, you can
  474.     otherwise rewrite the command entirely.  If you want to include
  475.     any special words in the new command, use the conventions described
  476.     below (for example, if you want to include 'and' in the new command,
  477.     use ',' instead).  After the new command inserted by preparseCmd()
  478.     has been processed, the parser will resume processing any remaining
  479.     commands on the player's original command line.
  480.  
  481.     The new command list returned by preparseCmd() can contain multiple
  482.     commands.  Simply separate the commands with commas (',') in your
  483.     list.
  484.  
  485.     If preparseCmd() returns a list, preparseCmd() will be invoked on
  486.     the new command.  However, preparseCmd() is not allowed to return
  487.     another new command in these cases -- if it does, the parser will
  488.     assume that preparseCmd() is looping, and will generate an error.
  489.  
  490.     Several new parseError codes have been added to respond to error
  491.     conditions that can arise from preparseCmd():
  492.  
  493.         32  Internal game error: preparseCmd returned an invalid list
  494.         33  Internal game error: preparseCmd command too long
  495.         34  Internal gmae error: preparseCmd loop
  496.  
  497.     The sample implementation of preparseCmd() below simply lists all
  498.     of the words in the current command and displays a newline, then
  499.     allows the command to proceed as usual.
  500.  
  501.         #pragma C+
  502.         preparseCmd: function(cmd)
  503.     {
  504.         local i, tot;
  505.     
  506.         for (i = 1, tot = length(cmd) ; i <= tot ; ++i)
  507.             "<<cmd[i]>> ";
  508.         "\n";
  509.         
  510.             return true;
  511.     }
  512.  
  513.     Note that the parser performs conversions of the special words.
  514.     These conversions will show up in the list as follows:
  515.  
  516.         "and"   becomes  ","
  517.         "all"   becomes  "A"
  518.         "but"   becomes  "X"
  519.         "it"    becomes  "I"
  520.         "them"  becomes  "T"
  521.         "him"   becomes  "M"
  522.         "her"   becomes  "R"
  523.         "any"   becomes  "Y"
  524.  
  525.     Here are some examples using the preparseCmd() function above.
  526.     (The actual response of the commands has been removed -- only the
  527.     text displayed by preparseCmd() is shown.)
  528.  
  529.         >look at all
  530.         look at A
  531.  
  532.         >examine him; take everything except the box and the book and go north
  533.         examine M
  534.         take A X the box , the book
  535.         go north
  536.  
  537.     preparseCmd() is called even for commands that the parser doesn't
  538.     understand.  This allows you to rewrite commands that TADS wouldn't
  539.     normally understand and put them into a format that's acceptable to
  540.     the parser.  For example, the preparseCmd() example below will
  541.     take sentences of the form "tell <actor> to <command>", and convert
  542.     them to the normal TADS syntax, "<actor>, <command>".
  543.         
  544.         #pragma C+
  545.         preparseCmd: function(cmd)
  546.     {
  547.         local i, tot, to_loc, actor, the_rest;
  548.  
  549.             tot = length(cmd);
  550.  
  551.         /* check to see if it starts with "tell" */
  552.         if (tot > 3 && cmd[1] == 'tell')
  553.         {
  554.             /* see if there's a word "to" */
  555.         for (i = 1, tot = length(cmd) ; i <= tot ; ++i)
  556.         {
  557.             if (cmd[i] == 'to')
  558.                 to_loc = i;
  559.         }
  560.  
  561.         /* if there's a "to", convert the command */
  562.         if (to_loc != nil && to_loc > 2)
  563.         {
  564.             /* find the parts before and after the 'to' */
  565.             for (i = 2, actor = [] ; i < to_loc ; ++i)
  566.                 actor += cmd[i];
  567.             for (the_rest = [], i = to_loc + 1 ; i <= tot ; ++i)
  568.                 the_rest += cmd[i];
  569.  
  570.             /* convert it to "actor, command" */
  571.             return actor + ',' + the_rest;
  572.         }
  573.         }
  574.  
  575.             /* otherwise, process the command as normal */
  576.             return true;
  577.         }
  578.  
  579.     When the parser doesn't know how to handle a sentence, it calls
  580.     preparseCmd with the entire rest of the command (which will include
  581.     everything before the next THEN or period), and processing is the
  582.     same as in any other case.  If preparseCmd() returns nil in this
  583.     case, the command is cancelled as usual without any further
  584.     processing by the parser.  If preparseCmd() returns true when the
  585.     sentence is not recognized by TADS, the parser will display the
  586.     usual message (parseError code 18, "I don't understand that
  587.     sentence").  If preparseCmd() returns a list of strings, the
  588.     command is replaced with the list, and the parser starts over
  589.     processing the new command.
  590.  
  591.   - Several new parseError codes have been added.
  592.  
  593.     In order to produce better messages when actors are involved,
  594.     the system now attempts to figure out whether an object in a
  595.     command refers to an actor, and if so, to determine whether the
  596.     actor should be called "him" or "her".  Previously, this
  597.     one-size-fits-all message was generated:
  598.  
  599.        What do you want to <verb> it <prep>?
  600.  
  601.     for example:
  602.  
  603.        >hit bill
  604.        What do you want to hit it with?
  605.  
  606.     Although it's not always possible to determine which object
  607.     should be used in these cases (because disambiguation will not
  608.     be possible until the indirect object is known), the system will
  609.     make its best guess.  To do so, it looks at all of the objects
  610.     that might be involved, based on the vocabulary.  If the player
  611.     appears to mean multiple objects, " them " will be used -- this
  612.     is message number 144 for parseError:
  613.  
  614.        >throw ball and bat
  615.        What do you want to throw them at?        <- message 144
  616.                                 ------
  617.  
  618.     If only one object appears to be intended, the parser will try
  619.     to figure out whether the object is male, female, or neuter,
  620.     using the isHim and isHer properties (these properties are not
  621.     new; they have been around since before TADS 2.0).  If all of
  622.     the objects that match a single noun phrase have isHim and
  623.     not isHer, " him " will be used -- this is parseError message
  624.     number 145:
  625.  
  626.       >hit bill
  627.       What do you want to hit him with?          <- message 145
  628.                              -----
  629.  
  630.     If they all have isHer and not isHim, " her " will be used
  631.     (message number 146):
  632.  
  633.       >hit jill
  634.       What do you want to hit her with?          <- message 146
  635.                              -----
  636.  
  637.     If both are set, the system equivocates with " them ", message
  638.     number 147 (note that this is the same default text as message
  639.     144, but it's distinguished as a separate message number in
  640.     case a game author wants a more suitable word in this case,
  641.     especially in a non-English language):
  642.  
  643.       >hit hermaphrodite
  644.       What do you want to hit them with?         <- message 147
  645.                              ------
  646.  
  647.     If not all of the objects involved have isHim and/or isHer
  648.     set, the system uses "it" (message 141) as in previous versions.
  649.  
  650.     Another change to the processing for this message involves
  651.     actors.  If an actor is specified in the command, the system
  652.     now builds a replacement for message 140.  First, message
  653.     148 is displayed, which has the default text "What do you want ".
  654.     Then, the actor's thedesc is invoked to display the actor's
  655.     name.  Finally, message 149 (default text " to ") is displayed,
  656.     and the rest of the message is built as before.
  657.  
  658.       >guard, throw ball
  659.       What do you want the guard to throw it at?
  660.       -----------------         ----
  661.          message 148             149
  662.  
  663.   - The functionality of the parseAskobj function has been extended
  664.     so that you can generate the same sort of message that the parser
  665.     now generates when a missing object is needed for a command directed
  666.     to an actor.  To provide the new functionality, the parser now calls
  667.     a function called parseAskobjActor.  This function is exactly the
  668.     same as parseAskobj, except that it takes the actor as the first
  669.     parameter, the verb as the second parameter, and the preposition
  670.     as an optional third parameter (which is only present when asking
  671.     for an indirect object).
  672.  
  673.     If your game defines parseAskobjActor, the system ignores parseAskobj
  674.     and calls the new function instead.  If parseAskobjActor is not defined,
  675.     but parseAskobj is defined, the system calls parseAskobj as it did in
  676.     past versions.  If neither function is defined, the system generates
  677.     the message itself as described above.  You should use parseAskobjActor
  678.     rather than parseAskobj for new games, since it gives you more
  679.     information.
  680.  
  681.     Here's an example of parseAskobjActor, which generates roughly the
  682.     same message as the system would (but it doesn't do any of the checking
  683.     of isHim and isHer to determine which pronoun to use -- this function
  684.     simply uses "it").
  685.  
  686.     parseAskobjActor: function(a, v, ...)
  687.     {
  688.         if (argcount == 3)
  689.         {
  690.             "What do you want ";
  691.                 if (a <> Me) a.thedesc;
  692.         " to <<v.sdesc>> it <<getarg(3).sdesc>>?";
  693.         }
  694.         else
  695.         {
  696.         "What do you want ";
  697.             if (a <> Me) a.thedesc;
  698.         " to <<v.sdesc>>?";
  699.         }
  700.     }
  701.  
  702.   - The parser has been changed slightly to allow a command to specify
  703.     an actor in any command within a single line containing multiple
  704.     commands.  Previously, if an actor was to be specified, the actor
  705.     had to be specified at the very beginning of the command.  This
  706.     restriction has been removed, which allows commands like this:
  707.  
  708.       >joe, north.  bob, south.  bill, east, take book, west.
  709.  
  710.     Note that, as in past versions, once an actor is specified, the
  711.     actor remains in effect for subsequent commands.  Since you could
  712.     only specify one actor for an entire command line in past versions,
  713.     this meant that the actor was used for every command on the line;
  714.     with this new version, an actor remains in effect until another
  715.     actor is specified.  So, in the command above, "north" is directed
  716.     to Joe, "south" is directed to Bob, and "east, take book, west"
  717.     is directed to Bill.
  718.  
  719.   - The maximum number of notifiers has been increased to 200.  The
  720.     maximum number of daemons and fuses has been increased to 100 each.
  721.  
  722.   - The maximum number of ambiguous words matching a particular
  723.     vocabulary word has been increased to 200.  This should relieve
  724.     problems that some people have reported with the error message
  725.     "The word 'foo' refers to too many objects".
  726.  
  727.   - The compiler now supports most of the remaining C operators:
  728.  
  729.         a % b      - returns the remainder of dividing a by b
  730.         a %= b     - sets a to a % b
  731.         a != b     - equivalent to a <> b
  732.         !a         - equivalent to (not a)
  733.         a & b      - bitwise AND
  734.         a &= b     - sets a to the bitwise AND of a and b
  735.         a | b      - bitwise OR
  736.         a |= b     - sets a to the bitwise OR of a and b
  737.         a && b     - equivalent to (a and b)
  738.         a || b     - equivalent to (a or b)
  739.         a ^ b      - bitwise XOR of a and b
  740.         a ^= b     - sets a to the bitwise XOR of a and b
  741.         ~a         - bitwise negation of a
  742.         a << b     - a shifted left by b bits
  743.         a <<= b    - shifts a left by b bits
  744.         a >> b     - a shifted right by b bits
  745.         a >>= b    - shifts a right by b bits
  746.  
  747.     Note a slight complication involving the >> operator:  you can't
  748.     use this operator from within an embedded string expression, because
  749.     it would be confused by the parser for the end of the expression.
  750.     It doesn't help to use parentheses, since the embedded string
  751.     processing is essentially a textual substitution mechanism which
  752.     happens without knowledge of the expression context (and is thus
  753.     unaware of parenthesization).  For example, this would be illegal:
  754.  
  755.        myprop = "x divided by 128 is << (x >> 7) >>!"     // wrong
  756.  
  757.     You would have to code this instead as:
  758.  
  759.        myprop = { "x divided by 128 is "; x >> 7; "!"; }  // right
  760.  
  761.     Another slight complication arises from the use of the & operator
  762.     in lists.  Since TADS allows list elements to appear without any
  763.     separating punctuation (except whitespace), you can have a list
  764.     that looks like this:
  765.  
  766.        mylist = [&sdesc &adesc &thedesc]
  767.  
  768.     This construct is still legal, and is still interpreted with the
  769.     "&" operators as unary operators, not bitwise AND operators.
  770.     However, the parser now warns when such a definition is used; see
  771.     the description of the new warning TADS-357 below for details.
  772.  
  773.   - The compiler will generate a new warning when it detects a unary
  774.     operator within a list that could also be interpreted as a binary
  775.     operator.  For example, in this list,
  776.  
  777.        list2 = [5 -2 -6 -7]
  778.  
  779.     the "-" operators could be interpreted either as unary negation
  780.     operators, which would result in a list with four elements (the
  781.     numbers 5, -2, -6, and -7), or as binary subtraction operators,
  782.     which would result in a list with only one element (the number
  783.     -10).  This same problem arises with the operators "+" and "&",
  784.     since these also have a unary and binary interpretation which
  785.     depends on context.
  786.  
  787.     In these cases, the compiler interprets the operators as unary
  788.     operators, and issues a warning to let you know that the usage
  789.     was ambiguous.  The warning is TADS-357:
  790.  
  791.       TADS-357: warning: operator '-' intepreted as unary in list
  792.  
  793.     Note that this is a change from the previous version for the '+'
  794.     and '-' operators.  If your game depends on building lists from
  795.     calculated numeric constants, you will need to change your code;
  796.     we don't expect that any games actually depend on the old behavior.
  797.  
  798.     If you really do want the operators in these cases interpreted
  799.     as binary operators, use parentheses:
  800.  
  801.        list2 = [(5 -2 -6 -7)]
  802.  
  803.     The parentheses tell the compiler that the expression is to be
  804.     interpreted as a single list element.
  805.  
  806.     If you want the unary interpretation, and you want to suppress
  807.     the warning, use commas between the list elements:
  808.  
  809.        list2 = [5, -2, -6, -7]
  810.  
  811.     This doesn't change the interpretation, but it does suppress the
  812.     warning, because it removes the ambiguity:  when the commas are
  813.     present, there is no way the '-' operators could be interpreted
  814.     as binary operators.
  815.  
  816.     You can suppress this warning using a new check box in the
  817.     compiler's warning level dialog.  Check the box to allow TADS-357
  818.     errors to be displayed.  You may want to suppress this warning when
  819.     compiling code written prior to this version of TADS, since the
  820.     warning is generated in case you wanted the new meaning of the &
  821.     operator.  The check box enabling the warning is checked by
  822.     default; uncheck it to suppress the warning.
  823.  
  824.   - A new compiler command-line option has been added:  -C, a toggle
  825.     option, which turns on and off C-language operator compilation.
  826.     By default, C operator mode is off (-C-), which makes the compiler
  827.     use the normal TADS operators.  Specifying -C+ turns on C operator
  828.     mode; specifying -C- disables C operator mode.
  829.  
  830.     When C-language operator mode is in effect, two operators are
  831.     affected:  the assignment operator becomes '=', and the equality
  832.     comparison operator becomes '=='.  With normal TADS operator mode
  833.     in effect, assignment is ':=' and equality is '='.  If you are
  834.     a C programmer, and you're unhappy with the slight variation in
  835.     operator notation between TADS and C, you can use -C+ to make TADS
  836.     behave more like a real language.  Thanks to the #pragma C options
  837.     (see below), C operator mode has no effect on your choice of
  838.     header files -- you can use the same old adv.t and other header
  839.     files unchanged, and still use C-style operators in your code.
  840.  
  841.   - A new preprocessor command has been added:  #pragma.  This special
  842.     directive can be used to specify certain compiler options from
  843.     within your source code.  Currently, the only #pragma option available
  844.     is the C operator mode option.  Use #pragma C+ to turn on C operator
  845.     mode, and #pragma C- to turn it off.
  846.  
  847.     The #pragma C+ and #pragma C- settings are local to a particular
  848.     file.  If a file is included by another file, the #pragma C settings
  849.     specified in the included file will be in effect only until the end
  850.     of the included file; the including file's #pragma C settings that
  851.     were in effect before including the other file will be restored at
  852.     the end of the included file.  adv.t and std.t now start with a
  853.     #pragma C- command -- this allows adv.t and std.t to be included
  854.     from a file with C-style operators (and thus a #pragma C+ or
  855.     command-line C operator mode setting).  Since the enclosing file's
  856.     #pragma C option will be restored after the inclusion, files with
  857.     different operator modes can be freely intermixed with #include, as
  858.     long as each included file specifies its desired mode with a
  859.     #pragma C directive.
  860.  
  861.   - The precedence of the comparison operators has been changed to
  862.     be the same as that used by C.  Previously, all of the comparison
  863.     operators were at the same precedence; starting with this version,
  864.     == and <> (and thus !=) are at the same level of precedence, and
  865.     associate left to right as before, but <, >, <=, and >= are one
  866.     level higher in precedence.  The following type of expression will
  867.     be affected:
  868.  
  869.           a > 1 <> b > 1
  870.  
  871.     Previously, this grouped as:
  872.  
  873.           (((a > 1) <> b) > 1   // obsolete
  874.  
  875.     This now groups as:
  876.  
  877.           (a > 1) <> (b > 1)    // current behavior
  878.  
  879.     This shouldn't affect any existing code, since the old interpretation
  880.     should always have resulted in an error (because a truth value, true
  881.     or nil, can not be compared in magnitude to a number or other type).
  882.  
  883.   - Limited conditional compilation and preprocessor text substitution
  884.     (#define) support has been added to the compiler.  The following
  885.     preprocessor directives are now available:
  886.  
  887.       #define symbol value
  888.       #undef symbol
  889.       #ifdef symbol
  890.       #ifndef symbol
  891.       #else
  892.       #endif
  893.  
  894.     #define is used to assign a value to a preprocessor symbol.  The
  895.     "value" is simply text that will be substituted verbatim for the
  896.     symbol whenever it occurs in your file (other than within quoted
  897.     strings).  For example:
  898.  
  899.       #define TEST say('hello from TEST!')
  900.  
  901.       myfunc: function
  902.       {
  903.          TEST;
  904.       }
  905.  
  906.     The symbol TEST is replaced with its definition, so the function
  907.     myfunc() displays "hello from TEST!" when called.
  908.  
  909.     Preprocessor symbols defined with #define are in a separate
  910.     namespace from all other symbols in your program.  Unlike a
  911.     standard C preprocessor, no arguments are allowed in #define
  912.     macros.
  913.  
  914.     #undef deletes a previously #define'd symbol.  You can #undef
  915.     the special symbols defined automatically by the compiler if
  916.     you wish (see below).
  917.  
  918.     #ifdef tests to see if a preprocessor symbol is defined.  If it
  919.     is, the lines following the #ifdef line, and up to the corresponding
  920.     #else or #endif, are included; otherwise, they are ignored.
  921.  
  922.     #ifndef is the opposite of #ifdef:  #ifndef tests to see if the
  923.     symbol is NOT defined.  If the symbol is undefined, the lines
  924.     following the #ifndef line up to the corresponding #else or
  925.     #endif are included; otherwise, they are ignored.
  926.  
  927.     #else indicates that the lines between the #else and #endif are
  928.     to be included if an only if the corresponding #ifdef (or #ifndef)
  929.     failed.  #else is optional.  At most one #else is allowed per
  930.     conditional.
  931.  
  932.     #endif terminates a conditional block.  Exactly one #endif must appear
  933.     for each conditional (#ifdef or #ifndef).
  934.  
  935.     You can use #ifdef to compile certain parts of your code
  936.     conditionally.  For example, if you want to include a verb only
  937.     for your debugging version of a game, but you want to remove it
  938.     from the final version, you could do something like this:
  939.  
  940.       #ifdef __DEBUG
  941.       magicVerb:  deepverb
  942.          verb = 'xyzzy'
  943.          action(actor) =
  944.          {
  945.          }
  946.       ;
  947.       #endif
  948.  
  949.     Note that __DEBUG is especially handy for this sort of thing,
  950.     because the compiler automatically defines this symbol when
  951.     debugging (-ds) is turned no (see below).
  952.  
  953.   - The compiler automatically defines several preprocessor symbols.
  954.     These symbols can be used or tested within your code as needed.
  955.  
  956.     __TADS_VERSION_MAJOR is defined to a number indicating the major
  957.     version number of the compiler (in the present system, 2).
  958.  
  959.     __TADS_VERSION_MINOR is defined to a number indicating the minor
  960.     version number (in the present system, 2).
  961.  
  962.     __TADS_SYSTEM is defined to a string (single-quoted) identifying
  963.     the operating system the compiler is running on.  In addition, the
  964.     same identifier contained in the string is defined as a preprocessor
  965.     symbol itself (its value is always 1; it is intended that it will
  966.     be tested with #ifdef, and not otherwise used).  For example, if
  967.     __TADS_SYSTEM is 'MSDOS', the symbol MSDOS will be defined to 1.
  968.     If __TADS_SYSTEM is 'Macintosh', the symbol Macintosh will be
  969.     defined to 1.
  970.  
  971.     __DEBUG is defined to 1 if debugging is turned on for this
  972.     compilation (with the -ds compiler option).  Otherwise, this symbol
  973.     is not automatically defined.  You can test the existence of __DEBUG
  974.     with #ifdef to conditionally include code only when you are compiling
  975.     for debugging.  This might be useful if you want to include certain
  976.     commands only in the debugging version of your game, and want to
  977.     remove them when you actually deliver the game to players.
  978.  
  979.     If this set of symbols were entered manually with #define statements,
  980.     the definitions might look like this:
  981.  
  982.       #define __TADS_VERSION_MAJOR  2
  983.       #define __TADS_VERSION_MINOR  2
  984.       #define __TADS_SYSTEM         'MSDOS'
  985.       #define MSDOS
  986.  
  987.     __DATE__ is defined as a single-quoted string giving the system date
  988.     when the compilation began, in the format "Jan 01 1980".
  989.  
  990.     __TIME__ is defined as a single-quoted string giving the system time
  991.     when the compilation began, in a 24-hour format, "13:40:50".
  992.  
  993.     __FILE__ is defined as a single-quoted string giving the file being
  994.     scanned at the point where the __FILE__ macro is encountered.  Each
  995.     time you use __FILE__, it will have the correct value for that point
  996.     in your source code.
  997.  
  998.     __LINE__ is defined as a number giving the line number at the point
  999.     where the __LINE__ macro is encountered.  Each time you use __LINE__,
  1000.     it will have the correct value for that point in your source code.
  1001.  
  1002.   - The compiler has two new options that give you further control
  1003.     over preprocessor symbols.  The -D option allows you to define
  1004.     a preprocessor symbol from the command line.  For example, to
  1005.     define TEST to 5 from the command line, you could do this:
  1006.  
  1007.       tc -i/tads/include -DTEST=5 mygame.t
  1008.  
  1009.     Note that if you omit the equals sign, the default definition
  1010.     of the symbol will be 1:
  1011.  
  1012.       tc -i/tads/include -DTEST mygame.t
  1013.  
  1014.     This defines TEST to 1.
  1015.  
  1016.     The -U option undefines a predefined symbol.  You can use this to
  1017.     undefine one of the symbols automatically defined by the compiler.
  1018.     You can also use it to undefine a symbol defined in a precompiled
  1019.     header, if you're loading one; -U is applied after the precompiled
  1020.     header is loaded, so it will undefine symbols loaded from the file.
  1021.     For example, to compile for debugging, but leave __DEBUG undefined,
  1022.     you could do this:
  1023.  
  1024.       tc -ds -U__DEBUG mygame.t
  1025.  
  1026.     The -U option is applied after all -D options, so you can also use
  1027.     it to undefine a symbol placed earlier on the command line.  This
  1028.     may be useful if you are using a configuation file (CONFIG.TC)
  1029.     that contains -D options for symbols you sometimes want to undefine.
  1030.  
  1031.   - The compiler has a new preprocessor directive, #error, which allows
  1032.     you to generate your own error during compilation.  If a #error
  1033.     directive is encountered, any text after the #error is displayed
  1034.     as a compiler error; an occurrence of #error is counted as an actual
  1035.     compilation error, so compilation will fail if #error is encountered.
  1036.     For example:
  1037.  
  1038.        #ifndef TEST
  1039.        # error TEST is not defined!
  1040.        #endif
  1041.  
  1042.     If the preprocessor symbol TEST is not defined at the point when
  1043.     this sequence is encountered, the compiler will display an error:
  1044.  
  1045.       mygame.t(181): error TADS-124: TEST is not defined!
  1046.  
  1047.   - The runtime has a new debugging feature that may help you track
  1048.     down problems with word definitions.  You can make the player
  1049.     command parser generate a number of status messages as it analyzes
  1050.     a player's command; these messages provide information on how the
  1051.     parser is interpreting the words in the command.
  1052.  
  1053.     To activate this new debug mode, use the debugTrace function with
  1054.     these arguments:
  1055.  
  1056.        debugTrace(1, true);
  1057.  
  1058.     To turn the debug mode off, call with nil instead of true.  This
  1059.     debugTrace function is always available, even when running under
  1060.     the normal runtime; the function returns no value when called with
  1061.     these arguments.
  1062.  
  1063.   - The built-in function incturn() has been extended to allow you
  1064.     to run a series of turns all at once.  You can now specify a numeric
  1065.     argument to incturn(); the argument gives the number of turns that
  1066.     should pass.  An argument of 1 causes incturn() to behave as usual.
  1067.  
  1068.     When an argument higher than 1 is given to incturn(), the function
  1069.     runs all of the fuses that are set to burn down within the number
  1070.     of turns specified, but not after that number of turns.  Note that
  1071.     the normal incturn() has never actually executed any fuses, but
  1072.     simply burns down all fuses by one more turn.
  1073.  
  1074.     For example, if you call incturn(2), the system will first run
  1075.     any fuses that are set to burn down after 1 turn, then will shorten
  1076.     all remaining fuses by one more turn.
  1077.  
  1078.   - A new built-in function, skipturn(), has been added.  This new
  1079.     function takes a numeric argument specifying the number of turns
  1080.     to skip; it must be at least 1.  skipturn(n) is similar to incturn(n),
  1081.     except that it does not run any of the fuses that burn down during
  1082.     the 'n' turns -- instead, it simply removes them without running
  1083.     them.
  1084.  
  1085.   - A new built-in function allows you to force capitalization off --
  1086.     this function, nocaps(), is the opposite of caps().  If you call
  1087.     caps() then call nocaps(), the next character is lower-case; if
  1088.     you call nocaps() then caps(), the next character is capitalized.
  1089.  
  1090.     Along with nocaps(), the special sequence \v has been added.  Using
  1091.     this sequence in a displayed string is equivalent to calling
  1092.     nocaps(); this sequence is analogous to \^, which is equivalent
  1093.     to calling caps().
  1094.  
  1095.   - The parser is now capable of disambiguating direct objects before
  1096.     indirect objects.  By default, everything works as it always has --
  1097.     in a two-object command, the indirect object is disambiguated first,
  1098.     and then the direct object is disambiguated in the presence of the
  1099.     known indirect object.
  1100.  
  1101.     It is now possible, however, to specify that the reverse should be
  1102.     done.  To do this, you use a new special flags syntax when defining
  1103.     your verb:
  1104.  
  1105.        tellVerb: deepverb
  1106.           verb = 'tell'
  1107.           desc = "tell"
  1108.           ioAction(aboutPrep) = [disambigDobjFirst] 'TellAbout'
  1109.        ;
  1110.  
  1111.     The new special flags are placed in square brackets between the
  1112.     equals sign and the property template for the verb definition.
  1113.     The flags currently accepted are:
  1114.  
  1115.        disambigDobjFirst
  1116.        disambigIobjFirst
  1117.  
  1118.     Note that disambigIobjFirst is provided for completeness only; it
  1119.     is never needed, because it is the default setting.
  1120.  
  1121.     When the disambigDobjFirst flag is specified, it means that the
  1122.     command should have its direct object disambiguated before its
  1123.     indirect object.
  1124.  
  1125.     When the disambiguation order is reversed, the normal argument
  1126.     lists for verDoTellAbout and verIoTellAbout are interchanged.
  1127.     For our example, the prototypes for the verifier methods become:
  1128.  
  1129.        verDoTellAbout(actor)
  1130.        verIoTellAbout(actor, dobj)
  1131.  
  1132.     Normally, verIoVerb would not receive the direct object as an
  1133.     argument, because the direct object would not be known at the time
  1134.     of the verIoVerb call; and verDoVerb would receive the indirect
  1135.     object as an argument, because it would be known by the time the
  1136.     direct object was being tested.  When the disambiguation order is
  1137.     reversed, however, so are the prototypes to these functions.
  1138.  
  1139.     The actual action method, ioTellAbout(actor, dobj), remains
  1140.     unchanged.  All other methods also remain the same.
  1141.  
  1142.     When the direct object is disambiguated first, the player is not
  1143.     allowed to use multiple direct objects (or multiple indirect objects)
  1144.     in the command.  If the player tries to do so, the new parseError
  1145.     message number 28 is displayed:
  1146.  
  1147.        >tell bob and bill about gun
  1148.        You can't use multiple objects with this command.
  1149.  
  1150.   - Note that a .GAM file format change was required to support the
  1151.     extra information needed for the disambigDobjFirst flag.  The TADS
  1152.     file format is now format "C".  The compiler is still capable of
  1153.     producing formats A or B, in case you need to generate .GAM files
  1154.     that can be played with versions prior to 2.2; however, if you
  1155.     use a format prior to C, you will not be allowed to use the
  1156.     disambigDobjFirst flag (or any other similar flags that may be
  1157.     added in the future).
  1158.  
  1159.   - Two new methods have been added to disambiguate actors.  Previously,
  1160.     the system validated and disambiguated an actor by pretending that
  1161.     you were attempting to take the actor -- takeVerb.validDo and the
  1162.     actor's verDoTake were used to validate and disambiguate the actor,
  1163.     when all you wanted to do was speak to him.  This did not always
  1164.     produce satisfactory results, and in particular did not allow for
  1165.     such situations as talking over a radio to an actor in another room.
  1166.     To provide better control over actor validation and disambiguation,
  1167.     the system for testing actors has been enhanced.
  1168.  
  1169.     First, to validate an actor, the system now uses the method
  1170.     validActor in the actor object itself.  This method takes no
  1171.     arguments; it returns true if the object is valid as an actor in
  1172.     a command, nil otherwise.  This method is called before the verb
  1173.     or any of the objects involved in the sentence are known.  Its
  1174.     function is not to determine whether the actor wants to receive
  1175.     the command, or even if the object can be used as an actor
  1176.     (actorAction is the place to do both of these tests), but rather
  1177.     simply to determine if the object can be addressed by the player
  1178.     at all.  This method should return true if the actor is accessible
  1179.     by voice command (or whatever other means you want to provide for
  1180.     giving commands) to the player.  The default thing.validActor in
  1181.     adv.t returns true if the object is reachable by Me, which provides
  1182.     roughly the same behavior as the old takeVerb-based mechanism.
  1183.  
  1184.     Second, to disambiguate an actor, the new preferredActor method
  1185.     has been added.  This method is called if an actor is ambiguous.
  1186.     As with validActor, it doesn't take any arguments, and it returns
  1187.     true if the object is "preferred" as an actor, nil otherwise.  If
  1188.     exactly one ambiguous object's preferredActor method returns true,
  1189.     the parser will use that object as the actor without further
  1190.     questioning the player; otherwise, the system will ask the player
  1191.     to disambiguate the noun as normal.  In adv.t, movableActor defines
  1192.     preferredActor = true.
  1193.  
  1194.     An example of how these might be used:
  1195.  
  1196.        Sleeping Compartment
  1197.           You are in a sleeping compartment on a moving train.
  1198.        A pair of bunks is along each wall.
  1199.           There is a copper wire here.
  1200.           The train conductor is standing in the doorway, asking for
  1201.        your ticket.
  1202.  
  1203.        >look at conductor
  1204.        Which conductor do you mean, the copper wire, or the train
  1205.        conductor?
  1206.  
  1207.        >copper
  1208.        It's a piece of wire, about a foot long.
  1209.  
  1210.        >conductor, where is ivan?
  1211.        "Your ticket, please," is all the conductor has to say.
  1212.  
  1213.     In this sequence, when the command is addressed to "conductor", the
  1214.     parser matches both the copper wire and the train conductor.  It
  1215.     checks validActor in each of them -- both return true, since both
  1216.     are accessible to the player.  (As described above, even though the
  1217.     copper wire couldn't possibly be an actor, it is valid as an actor
  1218.     at this point -- it's not until its actorAction that we will decide
  1219.     that there's no point in talking to it.)
  1220.  
  1221.     So, the parser has an ambiguous actor.  The parser tries to
  1222.     disambiguate the actor by testing preferredActor in each object.
  1223.     The copper wire's preferredActor returns nil; the train conductor's,
  1224.     however, returns true, because the conductor is a movableActor
  1225.     object.  The parser now has only one object, and thus doesn't
  1226.     need to ask the player for further information.
  1227.  
  1228.     For compatibility with games compiled with previous versions of
  1229.     adv.t, the parser will continue to use the old mechanism (involving
  1230.     the takeVerb) if validActor is not defined in your game.  Each time
  1231.     an actor is used, the parser checks to see if the first object in
  1232.     the list of possible actor objects has a validActor method defined;
  1233.     if not, the parser uses the old mechanism.  If you use the new adv.t,
  1234.     all objects will at least inherit a validActor method (from thing),
  1235.     so testing for the presence of this method in any object lets the
  1236.     parser determine if the new mechanism can be used with the game.
  1237.  
  1238.   - A new parseError message has been added:  number 27, whose default
  1239.     text is "You can't repeat that command."  This message is displayed
  1240.     when the player types AGAIN, but the parser can't repeat the command;
  1241.     this is the case if one of the objects involved in the command is
  1242.     no longer accessible.
  1243.  
  1244.   - A new parseError message has been added, related to validActor
  1245.     (see above).  This new message, number 31, is used when none of
  1246.     the objects matching the vocabulary for an actor in a player's
  1247.     command can be used as an actor.  The default text of this message
  1248.     is "You can't talk to that."  For example, if there is no object
  1249.     matching the vocabulary "guard" whose validActor method returns
  1250.     true, but an object named "guard" is visible to the player, the
  1251.     message is used:
  1252.  
  1253.       Security Room
  1254.           You are inside a small cubicle.  A thick, laser-proof
  1255.       (as you now know from your ill-fated attempt) glass door
  1256.       (closed) is to the north.  Through the door you can see
  1257.       a guard standing watch.
  1258.  
  1259.       >guard, open door
  1260.       You can't talk to that.
  1261.  
  1262.     This message is used for actors in place of the standard cantReach
  1263.     processing done for direct and indirect objects under these conditions.
  1264.  
  1265.   - A new parseError code, number 29, has been added.  The default
  1266.     message is "I think you left something out after 'any of'", and
  1267.     is used when the player uses "any of" in a sentence, but doesn't
  1268.     follow it with anything.
  1269.  
  1270.   - Using the same word as both a plural and a noun works much better
  1271.     now.  The parser will first attempt to use such a word as a plural;
  1272.     if no objects match the plural usage, the parser will try to use
  1273.     the word as a noun instead.
  1274.  
  1275.   - "of" can now be used as a preposition.  In previous versions of
  1276.     the run-time, "of" was exclusively a special word that was embedded
  1277.     in noun phrases (such as "pile of paper").  The runtime will still
  1278.     allow "of" to be used in noun phrases as before, but it also will
  1279.     treat "of" as an ordinary word when, based on the context, it does
  1280.     not appear to be part of a noun phrase.
  1281.  
  1282.     The parser will still attempt to treat "of" as part of a noun
  1283.     phrase whenever it matches an object.  For example, if you have
  1284.     an object with nouns matching "pile of paper", then the following
  1285.     interpretations will apply:
  1286.  
  1287.         accuse bob of murder   ->  dobj = bob, iobj = murder, prep = of
  1288.         accuse pile of paper   ->  dobj = pile of paper
  1289.  
  1290.     Note that ofPrep, defining "of" as a preposition, has been added
  1291.     to adv.t.
  1292.  
  1293.   - All of the system verbs that use "abort" have been modified
  1294.     slightly in adv.t to make it easier to augment their behavior
  1295.     with the 'modify' statement.  All of the processing other than
  1296.     the "abort" has been moved out of the doVerb (or action) method
  1297.     in each case, and put into a new method.  For example, saveVerb's
  1298.     action routine now looks like this:
  1299.  
  1300.         action( actor ) =
  1301.         {
  1302.         self.saveGame(actor);
  1303.         abort;
  1304.     }
  1305.  
  1306.     The new method saveVerb.saveGame(actor) now performs all of the
  1307.     processing that the action(actor) method previously performed.
  1308.  
  1309.     The benefit of this change is that you can now modify the
  1310.     saveGame(actor) method, and inherit the original behavior,
  1311.     without having to worry about an "abort" interfering with the
  1312.     order of operations.  For example:
  1313.  
  1314.         modify restoreVerb
  1315.             restoreGame(actor) =
  1316.             {
  1317.                 // restore the game as usual - check for success
  1318.                 if (inherited.restoreGame(actor))
  1319.                 {
  1320.                     // re-randomize the puzzle
  1321.             "The carnival hawker flashes a mischevious
  1322.             smile at you.  \"There's no use trying to
  1323.             guess the answer,\" he says.  \"I changed
  1324.             around the shells while you were busy
  1325.             restoring!\"";
  1326.             puzzle.answer := rand(100);
  1327.                 }
  1328.             }
  1329.         ;
  1330.  
  1331.  
  1332.   - The format mask fmtMe has been added.  You can now use %me% in
  1333.     messages to refer to the actor.  For basicMe, fmtMe is set to
  1334.     the message "me"; for other actors, it is set to the actor's
  1335.     thedesc.  In adv.t, thing.ldesc has been changed to use %me%:
  1336.     "It looks like an ordinary <<sdesc>> to %me%."  This makes the
  1337.     default sentence somewhat more adaptable if you ask another
  1338.     actor to describe something:
  1339.  
  1340.         >guard, look at the card
  1341.         It looks like an ordinary card to the guard.
  1342.  
  1343.   - AGAIN, WAIT, and SLEEP are now darkVerb's in adv.t.
  1344.  
  1345.   - A new verb, breakVerb, has been added to adv.t.  The vocabulary
  1346.     words for this verb are 'break', 'destroy', and 'ruin', and it
  1347.     provides a single-object command "break <direct-object>".  The
  1348.     thing class has been adjusted so that verDoBreak(actor) validates
  1349.     breaking any object, but doBreak(actor) simply displays "You'll have
  1350.     to tell me how to do that."  If you want to make a breakable object,
  1351.     simply override doBreak(actor) so that it breaks the object (you may
  1352.     also want to override verDoBreak(actor) so that it doesn't allow a
  1353.     broken object to be broken again).
  1354.  
  1355.   - "there" has been added a synonym for "it" in the specialWords list
  1356.     in adv.t.  This allows sentences like this:
  1357.  
  1358.         >get box.  put ball in there.
  1359.  
  1360.   - lightsource now has a doTurnnon method in adv.t.  This method will
  1361.     show the room's description if the room becomes lit as a result
  1362.     of turning on the lightsource.  Note that lightsource, by default,
  1363.     has no verDoTurnon, so you can't turn a generic light source on
  1364.     and off.  However, if you add switchItem to the superclass list of
  1365.     a lightsource object, you will have a light source that you can
  1366.     turn on and off, and which will have this new behavior.  Note that
  1367.     you should put lightsource in the superclass list prior to
  1368.     switchItem, so that lightsource.doTurnon overrides switchItem.doTurnon:
  1369.  
  1370.         flashlight:  lightsource, switchItem
  1371.             sdesc = "flashlight"
  1372.             noun = 'flashlight' 'light'
  1373.             adjective = 'flash'
  1374.             location = tunnel
  1375.         ;
  1376.  
  1377.   - verIoGiveTo and ioGiveTo have been added to movableActor in adv.t.
  1378.     verIoGiveTo rejects the command if the actor is the same as the
  1379.     indirect object, otherwise the command is accepted.  ioGiveTo
  1380.     always rejects the offer.  In addition, ioGiveTo has been added
  1381.     to basicMe; the method always accepts anything from another actor,
  1382.     because this method will only be called in response to commands
  1383.     such as:
  1384.  
  1385.         >guard, give me the key
  1386.  
  1387.   - A small problem with thing.isVisible in adv.t has been fixed.  If
  1388.     the vantage is inside the object, and the object's contents are
  1389.     visible, isVisible returns true.  This is is needed in certain
  1390.     situations involving nested rooms.
  1391.  
  1392.   - moveableActor.travelTo(room) in adv.t has been corrected so
  1393.     that it does nothing when room = nil, which is the case when the
  1394.     actor can't travel in the desired direction.  Previously, the
  1395.     "noexit" message would be displayed, but then the actor would
  1396.     be moved into a nil location.
  1397.  
  1398.   - moveableActor now has a roomCheck method in adv.t.  The method
  1399.     is the same as basicMe's roomCheck method; its omission in
  1400.     previous versions was an oversight.
  1401.  
  1402.   - The compiler now sets an error code on exit.  If you are using
  1403.     a MAKE utility or other program-building tool, you can use the
  1404.     exit code.  On success, the compiler uses exit code 0; if any
  1405.     errors occurred, a non-zero exit code is used.
  1406.  
  1407.   - The compiler no longer creates a .GAM file if errors occurred
  1408.     during compilation.  If a .GAM file of the same name exists
  1409.     prior to a compilation, and errors occur, the original .GAM
  1410.     file is unaffected (it is not deleted or overwritten).  Although
  1411.     the compiler previously produced a .GAM file even when an error
  1412.     occurred, this .GAM file was not generally usable; to avoid
  1413.     confusion, the compiler no longer produces a .GAM file at all
  1414.     when an error occurs.
  1415.  
  1416.   - The compiler performs more checking for invalid memory options.
  1417.     When memory options are entered that exceed the compiler's
  1418.     internal limits, the compiler will report an error (after the
  1419.     Compile button is pushed) and halt the compilation.  The affected
  1420.     settings are the parse pool size, local symbol table size, and
  1421.     the stack size.  The runtime similarly checks its parameters
  1422.     more carefully now.
  1423.  
  1424.   - $$ABEND can now be used after a question from the parser, such
  1425.     as during disambiguation and when OOPS is permitted.
  1426.  
  1427.   - The runtime no longer displays anything on the status line at
  1428.     startup.  It initializes both the left portion (which normally is
  1429.     used to display the location) and the right portion (which is
  1430.     normally used to display the score and turn count) to empty
  1431.     strings.  To ensure that a score is properly displayed at the
  1432.     start of the first turn, we added a call to scoreStatus(0, 0) in
  1433.     the "init" function defined in std.t.
  1434.  
  1435.   - The runtime handles hyphenation better.  Multiple hyphens will
  1436.     no longer be split across lines -- so if you use two hyphens
  1437.     together for a dash, both hyphens will always be grouped on one
  1438.     line.  Furthermore, the runtime formatter will never put a dash
  1439.     at the very start of a line; if a line must be split at a dash,
  1440.     the formatter will put the dash at the end of the line, then
  1441.     break the line, and will back up and split at the previous word
  1442.     if necessary.
  1443.  
  1444.   - The runtime will now properly convert "\" sequences in askfile()
  1445.     prompts properly.  If you use a \n, \t, \', \", or \\ sequence
  1446.     in a prompt to askfile(), the sequence will be displayed as the
  1447.     appropriate character.
  1448.  
  1449.   - The Mac runtime's startup dialog has an additional option that
  1450.     lets a user show all files, rather than just files that the
  1451.     runtime recognizes as TADS game files.  This should make it
  1452.     easier to run a game transferred from another system -- since
  1453.     you can now run a game regardless of its type/creator settings,
  1454.     you can simply transfer a file from another operating system and
  1455.     run it directly.  To show all files, click the radio button
  1456.     labelled "Show All Files" at the bottom of the file dialog;
  1457.     to return to showing only TADS game files, click the radio
  1458.     button labelled "Show TADS Games Only."
  1459.  
  1460.   - The TADS Executable Game Builder now lets you specify run-time
  1461.     command options that should be used when the game is executed.
  1462.     This new feature, which is optional, lets you specify a set of
  1463.     run-time options that you want to be in effect every time your
  1464.     game is run.
  1465.  
  1466.     To specify command options for your game executable, you must
  1467.     first create a file.  Use the same format as CONFIG.TR -- simply
  1468.     enter your options into the file as you would on a TR command
  1469.     line; separate options by newlines or spaces.  For example, to
  1470.     specify a minimal cache size and a swap file of SWAP.DAT, you
  1471.     could make your CONFIG.TR file look like this:
  1472.  
  1473.         -m0 -tf swap.dat
  1474.  
  1475.     See the Author's Manual chapter on the run-time command-line
  1476.     options.  Even though the Macintosh version of the run-time
  1477.     doesn't normally use a command line at all, you must still enter
  1478.     options into a file using the command line option format if you
  1479.     want to combine them with your game.
  1480.  
  1481.     Once you've created a file with your command options, specify
  1482.     that file to the Executable Game Builder by selecting it with
  1483.     the new file selector dialog that appears after you specify the
  1484.     game file.  If you don't want to combine an options file with
  1485.     your game, simply cancel this dialog.
  1486.  
  1487.     Once the config file is bound into your executable, its options
  1488.     will be used every time a player runs the game.  Note that you may
  1489.     want to avoid specifying anything specific to your system, such as
  1490.     volume or folder names, since that may prevent the game from working
  1491.     properly on someone else's computer.
  1492.  
  1493.   - The Macintosh compiler's "memory options" dialog box has been
  1494.     corrected so that it accepts settings over 32767.  Memory settings
  1495.     up to 65535 can now be entered.
  1496.  
  1497.   - The Macintosh compiler no longer displays "Compilation Completed"
  1498.     when compilation fails or is interrupted.  Instead, it displays
  1499.     the new message "Compilation Terminated", to make it clear that
  1500.     the compilation did not complete normally, whenever errors occur
  1501.     during a compile, or the compilation is cancelled by Command-Period.
  1502.  
  1503.   - The Macintosh compiler has been corrected so that it doesn't add
  1504.     ".t" to the end of source file names any more.  In previous versions,
  1505.     the compiler always added ".t" to the end of a filename if the
  1506.     filename didn't contain at least one period; while this behavior
  1507.     is desirable on other computers (since it allows command-line
  1508.     users to omit the default filename extension, saving typing), it's
  1509.     unnecessary and incorrect on the Macintosh.
  1510.  
  1511.   - The Macintosh run-time's formatting system has been improved so
  1512.     that it will no longer insert spaces after hyphens.  Previous
  1513.     versions occasionally inserted a space after a hyphen, even when
  1514.     the original text had no spaces after the hyphen.
  1515.  
  1516.   - The new sentence parsing for the form VERB PREP IOBJ DOBJ
  1517.     (introduced in 2.1.1) causes a subtle problem:  if you create
  1518.     an object with an adjective that is also a preposition, the
  1519.     system attempts to interpret sentences with a single-word verb
  1520.     that refers to the object as VERB PREP IOBJ.  The result is
  1521.     this:
  1522.  
  1523.        >push off button
  1524.        What do you want to push?
  1525.  
  1526.     This is because the parser is interpreting the sentence as
  1527.     "push something off button", and needs to know the "something".
  1528.     This problem has been corrected.  Now, the parser will check this
  1529.     type of case to see if the preposition can also be used as an
  1530.     adjective, and if so, checks to see if a noun (possibly preceded
  1531.     by one or more adjectives) follows; if this test is met, the word
  1532.     will be interpreted as an adjective, as it should be.
  1533.  
  1534.   - The parser now correctly distinguishes between cases involving
  1535.     a word that is defined as both a preposition and an adjective.
  1536.     The parser previously did not accept sentences such as this:
  1537.  
  1538.       >enter south wall
  1539.  
  1540.     when 'south' was defined as an adjective.  Because 'south' was
  1541.     also defined as a preposition (in adv.t), the parser attempted
  1542.     to interpret this sentence as though 'enter south' were a verb
  1543.     (in the same manner as 'pick up' or 'put down').  The parser
  1544.     now checks to make sure that 'enter south' is a valid combination
  1545.     verb; if it's not, and 'south' is also defined as another part of
  1546.     speech, the parser assumes that 'enter' is the verb, and treats
  1547.     'south' as an adjective.
  1548.  
  1549.   - The parser previously asked to disambiguate a direct object twice
  1550.     if askio(prep) was used.  For example:
  1551.  
  1552.        >unlock door
  1553.        Which door do you mean, the large door, or the small door?
  1554.  
  1555.        >large
  1556.        What do you want to unlock it with?
  1557.  
  1558.        >key
  1559.        Which key do you mean, the silver key, or the gold key?
  1560.  
  1561.        >gold
  1562.        Which door do you mean, the large door, or the small door?
  1563.  
  1564.        >large
  1565.        The door unlocks with a satisfying click.
  1566.  
  1567.     This has been corrected -- the parser now only asks once about
  1568.     the door.
  1569.  
  1570.   - The parser did not previously accept a word during disambiguation
  1571.     if the word was defined as both a noun and an adjective.  For
  1572.     example, if you've defined objects "violet paper", "violet banana",
  1573.     and "paper towel", and the parser asked you this:
  1574.  
  1575.        >x violet
  1576.        Which violet do you mean, the violet paper, or the violet banana?
  1577.  
  1578.     then you couldn't respond with "paper".  This has been corrected.
  1579.  
  1580.   - The inputkey() function now clears the "more" line counter.  So,
  1581.     when inputkey() is called, a "more" prompt will not show up until
  1582.     another screenful of text has been displayed.
  1583.  
  1584.   - "local" statements that occur out of context (i.e., as other than
  1585.     the first statements after an open brace) now generate better
  1586.     diagnostics.
  1587.  
  1588.   - Dividing by zero is now flagged as a run-time error.
  1589.  
  1590.   - A problem involving the embedded string << >> notation has been
  1591.     corrected.  Under certain circumstances, if one expression used
  1592.     in an embedded string invoked another string with an embedded
  1593.     expression, an error occurred (usually "invalid type for built-in
  1594.     function").  This should no longer occur.
  1595.  
  1596.   - The system did not properly handle lists containing function
  1597.     pointers.  This has been corrected.
  1598.  
  1599.   - A problem involving pre-compiled headers and 'modify' has been
  1600.     corrected.  Several people have encountered problems that generally
  1601.     were manifested as "assert" failures in mcm.c (the cache manager)
  1602.     when using 'modify' and pre-compiled headers; these should no
  1603.     longer occur.
  1604.  
  1605.   - An internal cache corruption occurred under certain obscure
  1606.     circumstances involving 'modify'.  This has been corrected.
  1607.  
  1608.   - A note on roomCheck:  if you return nil from roomCheck, fuses
  1609.     and daemons are NOT run; in this sense, returning nil from roomCheck
  1610.     is equivalent to using abort in other methods.  (This is not a
  1611.     change -- it's always worked this way -- but this behavior is
  1612.     not mentioned in the TADS Author's Manual.)
  1613.  
  1614.   - A note on using << >> embedded strings:  If you put a newline
  1615.     immediately before the << of an embedded string, any spaces between
  1616.     the last non-space character preceding the << and the << will be
  1617.     lost.  If you want a space before the <<, do not put it on a new
  1618.     line.  Instead, you can put it at the end of the line, and put
  1619.     the embedded expression itself on the next line.  For example:
  1620.  
  1621.         embeddedString = "embedded string"
  1622.         sdesc = "This is a message with an
  1623.                  <<self.embeddedString>>!"     // wrong
  1624.  
  1625.     This will display as follows:
  1626.  
  1627.         This is a message with anembedded string!
  1628.  
  1629.     If you intend a space to precede the embedded string, you should
  1630.     write this as follows:
  1631.  
  1632.         sdesc = "This is a message with an <<
  1633.                 self.embeddedString>>!";      // right
  1634.  
  1635.     (This is not a change, but simply a note for game developers who
  1636.     have encountered this problem.)
  1637.  
  1638.  
  1639.  
  1640. 2.1.2  11/22/93  enhancements, bug fixes
  1641.  
  1642.   - You can now detect when the player uses multiple direct objects
  1643.     with a verb, and reject such commands.  Whenever the player uses
  1644.     multiple direct objects with a command (or uses "all", even if it
  1645.     results in a single object being used), the parser calls the
  1646.     verb object's rejectMultiDobj(prep) method.  If you don't wish to
  1647.     take any special action for multiple direct objects used with a
  1648.     particular verb, simply return nil from this method (or don't
  1649.     define the method at all for the verb).  If you want to prevent
  1650.     multiple direct objects from being used, however, you should display
  1651.     an appropriate message, and return true.  The parser will skip the
  1652.     command entirely.  Note that the parser doesn't display any additional
  1653.     message when rejectMultiDobj(prep) returns true; the method should
  1654.     display whatever message is desired.  The "prep" parameter is the
  1655.     preposition object used with the command; it will be nil if no
  1656.     indirect object is present.  An example:
  1657.  
  1658.         modify inspectVerb
  1659.             rejectMultiDobj(prep) =
  1660.             {
  1661.                 "You can only look at one thing at a time.";
  1662.                 return true;
  1663.             }
  1664.  
  1665.     The verb's rejectMultiDobj(prep) method is called immediately
  1666.     before the actor's actorAction method.  Note that the parser will
  1667.     continue processing any remaining commands on the line, and will
  1668.     then run daemons and fuses as normal, even if rejectMultiDobj(prep)
  1669.     returns true; if you want to stop the current turn altogether, use
  1670.     abort.
  1671.  
  1672.   - The player command parser now gives you greater control over object
  1673.     validation error reporting.  In previous versions, if an object was
  1674.     visible but did not pass the validIo/validDo test, the parser called
  1675.     the object's cantReach method to report the error (see the note below
  1676.     about an additional change to object.cantReach processing).
  1677.  
  1678.     Now, however, the parser will call verb.cantReach instead, if the
  1679.     command's deepverb object defines (or inherits) a cantReach method.
  1680.     If the verb does not have a cantReach method at all, the parser
  1681.     will use the old behavior instead.  The new cantReach method should
  1682.     be defined as follows:
  1683.  
  1684.        myVerb: deepverb
  1685.            verb = 'whatever'
  1686.            cantReach(actor, dolist, iolist, prep) =
  1687.            {
  1688.                // your code here
  1689.            }
  1690.        ;
  1691.  
  1692.     This method doesn't return a value; it simply displays the appropriate
  1693.     message explaining why the object can't be used with the command.
  1694.     verb.cantReach is used only when the objects are visible (that is,
  1695.     object.isVisible(actor) returned true for each object in the list).
  1696.  
  1697.     Only one of dolist or iolist will be non-nil.  If the direct object
  1698.     of the command refers to one or more objects that are visible but
  1699.     can't be used (according to validDo), dolist will be a list of all
  1700.     such objects, and iolist will be nil.  Otherwise, iolist will be a
  1701.     list of such objects used for the indirect object, and dolist will
  1702.     be nil.
  1703.  
  1704.     adv.t has not been changed to use verb.cantReach.  This change has
  1705.     been made to provide finer control for game authors implementing
  1706.     their own verbs and object validation procedures.
  1707.  
  1708.   - The player command parser had an odd quirk when ambiguous nouns
  1709.     were used with transparent items.  If the player used a command
  1710.     containing a noun that referred to multiple objects that were
  1711.     visible but were not valid for the verb (for example:  "take trophy"
  1712.     in a room containing a closed glass trophy case containing a bowling
  1713.     trophy and a tennis trophy), the parser asked the normal disambiguation
  1714.     question.  This was not really necessary, because the parser already
  1715.     knew that the objects were invalid.  This has been changed; the parser
  1716.     now simply uses the cantReach message for *each* object that is
  1717.     visible and matches the vocabulary, using the usual multiple-word
  1718.     format:
  1719.         bowling trophy:  You'll have to open the glass case first.
  1720.         tennis trophy:  You'll have to open the glass case first.
  1721.  
  1722.     This new behavior should have no effect on your game code.  Note
  1723.     that it is entirely irrelevant if you use the new verb.cantReach
  1724.     feature described above.
  1725.  
  1726.   - The compiler sports a new case sensitivity option.  By default,
  1727.     the compiler is case-sensitive, as it has been in past versions.
  1728.     However, the new toggle option allows you to change this.  Specify
  1729.     -case- to turn off case sensitivity (the default is -case+).  Note
  1730.     that this is a toggle option, so simply using -case will reverse
  1731.     the current case sensitivity (which is useful if you use a CONFIG.TC
  1732.     file that sets a non-default case option).  When case sensitivity
  1733.     is turned off, the compiler will treat upper- and lower-case letters
  1734.     in symbols (names of objects, properties, functions, and local
  1735.     variables) as equivalent.  Hence, foodItem = fooditem = FoodItem,
  1736.     and so on.
  1737.  
  1738.     If you create a pre-compiled header with -w, any compilation which
  1739.     reads that binary header with -l will use the same case sensitivity
  1740.     as was in effect when the header was pre-compiled.  The -case option
  1741.     is ignored when a pre-compiled header is loaded.  Likewise, the
  1742.     debugger uses the same case sensitivity that was in effect when the
  1743.     game being debugged was compiled.
  1744.  
  1745.   - The debugger's command set is no longer case-sensitive (hence,
  1746.     BP = Bp = bP = bp).
  1747.  
  1748.   - adv.t has a new darkVerb class.  This is a type of deepVerb that
  1749.     can be used in the dark.  The darkroom class has been changed to
  1750.     accept any verb of class darkVerb in its roomAction and roomCheck
  1751.     methods.  The travel verbs and system verbs have all been made
  1752.     darkVerb objects, so darkroom only needs to check the single
  1753.     verb type.
  1754.  
  1755.     In a related change, turnOnVerb and dropVerb have been changed to
  1756.     be darkVerb objects, allowing the player to turn on an object or
  1757.     drop it in the dark.  The verDoTurnon method in switchItem has
  1758.     been changed so that it checks to see if the player is in a dark
  1759.     room; if so, the item can only be turned on if the player is already
  1760.     carrying the object.  This allows the player to turn on a light
  1761.     source that's already being carried, but doesn't allow the player
  1762.     to pick up a light source in a dark room.
  1763.  
  1764.   - The compiler issues a new warning message (TADS-452) if you
  1765.     use the same verb with two deepverb objects.  The parser can only
  1766.     choose a single deepverb object for any verb typed by the player,
  1767.     so you should never define the same 'verb' vocabulary word in more
  1768.     than one deepverb object.  In past versions, the compiler did not
  1769.     flag this as a warning.
  1770.  
  1771.   - Several improvements have been made for numbers in player
  1772.     commands.  First, multiple numbers are now allowed in a single
  1773.     commands; for example, the player can now say "press 1, 2, 3,
  1774.     4 on keypad," and the numbers are set in numObj.value, one by
  1775.     one.  Second, the sdesc, adesc, and thedesc properties of
  1776.     basicNumObj have been improved to show the number's value.
  1777.  
  1778.   - Similar improvements to those for numbers have been made for
  1779.     strings.  Multiple strings are now allowed in a single command,
  1780.     and the basicStrObj properties sdesc, adesc, and thedesc have
  1781.     been improved to show the string's value.
  1782.  
  1783.   - specialWords has been enhanced.  First, in past versions, if a
  1784.     game contained multiple specialWords statements, the word lists
  1785.     were additive -- all specialWords lists were used in the game.
  1786.     This has been changed so that each specialWords statement replaces
  1787.     any previous list in effect.  However, you now can explicitly add
  1788.     to the specialWords list, without removing any of the previously
  1789.     defined words, by using "modify specialWords".  When you use
  1790.     'modify', you can use nil in any word slot if you do not wish
  1791.     to add any words for that slot.  Finally, you can use "replace
  1792.     specialWords" to make the replacement explicit; this is the default
  1793.     if neither 'modify' nor 'replace' is specified, but the compiler
  1794.     will now issue a warning (which is harmless) if you use specialWords
  1795.     without 'replace' or 'modify' and a previous specialWords list is
  1796.     already in effect.
  1797.  
  1798.   - The words "one" and "ones" (or their equivalent for your game,
  1799.     if you've changed them with specialWords) are no longer considered
  1800.     reserved words within normal commands.  This allows you to use
  1801.     objects such as a "one dollar bill"; previous versions rejected
  1802.     player commands containing "one" or "ones".  These words are now
  1803.     considered special only during the parsing of a response to a
  1804.     disambiguation question, when they can be used in place of a
  1805.     noun ("the red one" can be used in answer to "Which book do you
  1806.     mean...").
  1807.  
  1808.   - The hider class has been changed so that 'it' or 'them' (as
  1809.     appropriate) are set to the object or objects found when
  1810.     searching the hider.
  1811.  
  1812.   - The verDoPutIn and verDoPutOn messages in thing and surface
  1813.     (respectively) have been improved for the somewhat obscure case
  1814.     of attempted circular containment - that is, putting an object
  1815.     into a container, when the container is already in the first object
  1816.     (either directly or by virtue of being inside another object which
  1817.     is inside the first object, or inside an object which is inside an
  1818.     object which is inside the first object, and so on).  The new
  1819.     method thing.circularMessage(iobj) is called in these cases to
  1820.     display an appropriate message; the default implementation of this
  1821.     method displays the complete list of containers of the direct
  1822.     object out to the indirect object.  For example, if you have a
  1823.     crate which contains a box, and you try to "put crate in box",
  1824.     the message is "You can't put the crate in the box, because
  1825.     the box is already in the crate."
  1826.  
  1827.   - The default doTake method has been changed to include the weight
  1828.     of any contents of the item being taken, in addition to the item
  1829.     itself, to determine if the actor's inventory is too heavy.
  1830.     The old doTake method only included the weight of the object
  1831.     being taken, not counting its contents.
  1832.  
  1833.   - The Actor class has been changed to add a travelTo method.  You
  1834.     can now move any actor (Me included) with travelTo(destination).
  1835.     The default Actor.travelTo method moves the actor; it announces
  1836.     the departure of the actor if the actor was in the same location as
  1837.     Me before leaving (and the location is lit); and it announces the
  1838.     arrival of the actor if the actor is moving into the same location
  1839.     as the player (and the location is lit).  The departure message
  1840.     is generated with a call to self.sayLeaving, and the arrival
  1841.     message is generated with self.sayArriving.  The default versions
  1842.     of these methods simply display "Thedesc leaves the area" and
  1843.     "Thedesc enters the area", respectively; you can override these
  1844.     methods if a more specific message is desired.
  1845.  
  1846.   - When modifying a class object with 'modify', the modified object
  1847.     was not a class unless the 'class' keyword was included with the
  1848.     'modify' statement ("modify class foo" rather than "modify foo").
  1849.     This has been corrected; a modified class is still a class.
  1850.  
  1851.   - outhide(true) now returns a status indicator, which is a value that
  1852.     can be used in a subsequent call to outhide() to return output
  1853.     hiding to the state it was in before the outhide(true).  This
  1854.     allows you to nest text hiding.  When you use the nested form
  1855.     (which you do simply by using the return value of outhide(true) as
  1856.     the parameter - in place of nil - to the subsequent call to outhide()),
  1857.     the value returned by the second outhide() indicates whether any
  1858.     text output occurred ONLY BETWEEN THE NESTED CALLS.  For example:
  1859.     
  1860.      old_stat1 := outhide(true);
  1861.      "This is some hidden text.";
  1862.      old_stat2 := outhide(true);
  1863.      // write no text here
  1864.      new_stat2 := outhide(old_stat2);
  1865.      new_stat1 := outhide(old_stat1);
  1866.  
  1867.     Because outhide(old_stat2) indicates whether any output occurred
  1868.     during the NESTED outhide(true), new_stat2 = nil.  However, new_stat1
  1869.     = true, since output occurred after the first outhide(true).  Consider
  1870.     another sequence:
  1871.  
  1872.      old_stat1 := outhide(true);
  1873.      // write no text here
  1874.      old_stat2 := outhide(true);
  1875.      "This is some hidden text.";
  1876.      new_stat2 := outhide(old_stat2);
  1877.      new_stat1 := outhide(old_stat1);
  1878.  
  1879.     In this case, both new_stat1 and new_stat2 will be true, because
  1880.     hidden output occurred within both nested sections.
  1881.  
  1882.     The general form of a nested hidden output section looks like this:
  1883.  
  1884.          {
  1885.             local original_hide_stat;
  1886.         local nested_stat;
  1887.  
  1888.             original_hide_stat := outhide(true);
  1889.             // do whatever you want to do while output is hidden
  1890.         nested_stat := outhide(original_hide_stat);
  1891.      }
  1892.  
  1893.     Now nested_stat will indicate whether any output occurred during
  1894.     the nested outhide() - that is, between the outhide(true) and
  1895.     the outhide(original_hide_stat).  In addition, output hiding will
  1896.     be returned to the same state it was in prior to the original
  1897.     outhide(true).
  1898.  
  1899.   - The random number generator has been improved.  Many people have
  1900.     complained about the many undesirable properties of the old
  1901.     generator, especially when small upper limits were used.  The
  1902.     interface to the new random number generator is the same as
  1903.     before - call rand(upper_limit), which will return a uniformly
  1904.     distributed random number from 1 to upper_limit, inclusive.
  1905.  
  1906.     Note that the old random number generator will still be used if
  1907.     you don't call randomize().  This allows test scripts (which require
  1908.     a fixed sequence of random numbers in order to be repeatable) that
  1909.     were written with older versions to continue to operate unchanged.
  1910.     If you want numbers from the improved generator, be sure to call
  1911.     randomize().
  1912.  
  1913.   - When 'modify' was used on an object, the compiler sometimes did
  1914.     not correctly apply the original object's vocabulary and location
  1915.     to the new object.  This has been corrected.
  1916.  
  1917.   - restore() and undo() have been changed so that they always cancel
  1918.     all pending commands on the command line.  In the past, if the
  1919.     player typed several commands, and something happened (such as
  1920.     the player character dying) during one of the commands that led to
  1921.     an undo() or restore(), the remaining commands were still
  1922.     executed.  This has been fixed.
  1923.  
  1924.   - If you explicitly set an object's location to nil in its object
  1925.     definition, and the object inherited a location from a superclass,
  1926.     the system incorrectly placed the object in the contents list of
  1927.     the object named in the location inherited from the object's
  1928.     superclass.  This has been corrected.
  1929.  
  1930.   - "abort" can now be used within a daemon or fuse, and the
  1931.     expected behavior will occur.  In the past, "abort" within
  1932.     a fuse (or daemon) merely exited from the current fuse,
  1933.     but the remaining fuses and daemons were still executed.
  1934.     Now, "abort" will cause the entire turn to end; no more
  1935.     fuses or daemons will be executed on the current turn.
  1936.  
  1937.  
  1938. 2.1.1  09/09/93  enhancements
  1939.  
  1940.   - You can now access objwords(1) while deciding whether to use a
  1941.     default direct object in doDefault.  This is useful mostly if
  1942.     you want to prevent players from being able to use "all" with
  1943.     certain verbs, but still want to generate a default direct object
  1944.     for the verbs.  To do this, you can detect when objwords(1) = ['A']
  1945.     ('A' is the parser's internal code for "all", which saves you the
  1946.     trouble of checking for "everything" and shorter abbreviations as
  1947.     well as "all"):
  1948.  
  1949.       doDefault(actor, prep, iobj) =
  1950.       {
  1951.           if (objwords(1) = ['A'])
  1952.           {
  1953.               global.allMessage := 'You can\'t use "all" with this verb.';
  1954.           return [];
  1955.       }
  1956.  
  1957.       /* your normal default object code goes here */
  1958.       }
  1959.  
  1960.     If you wish, you can also suppress the default message that the
  1961.     parser will generate ("I don't see what you're referring to").
  1962.     To do this, you'll have to write your own parseError() function
  1963.     and detect when an "all" violation has occurred (cleverly using the
  1964.     global.allMessage, which we set above for this purpose):
  1965.  
  1966.       parseError: function(str, num)
  1967.       {
  1968.           // if there's an allMessage waiting, use it instead of the default
  1969.           if (global.allMessage <> nil)
  1970.       {
  1971.           local r;
  1972.  
  1973.           r := global.allMessage;
  1974.           global.allMessage := nil;
  1975.           return r;
  1976.       }
  1977.       else
  1978.           return nil;
  1979.       }
  1980.     
  1981.   - The compiler's error message format has been changed slightly
  1982.     to work better with editors and workbench programs that scan error
  1983.     logs to go to lines with errors.  The format is now:
  1984.  
  1985.         file(line): error TADS-xxxx: message
  1986.  
  1987.     For example:
  1988.  
  1989.         deep.t(1151): error TADS-300: expected colon
  1990.  
  1991.  
  1992.   - The parser now accepts sentences of the form VERB PREP IOBJ DOBJ,
  1993.     where the PREP is *not* part of the verb.  For example, GIVE TO THE
  1994.     MAN THE BALL.  This change has two benefits.  First, while this
  1995.     type of sentence is not common in English, some other languages
  1996.     allow this type of phrasing, so the parser is now somewhat more
  1997.     adaptable to non-English languages.  Second, this allows for
  1998.     object defaulting and command completion when specifying just the
  1999.     indirect object, which was not possible before.  For example, if
  2000.     the player types ASK FOR A BEER, the parser will be able to attempt
  2001.     to provide a default (if one is available), or at least ask for the
  2002.     direct object.  Previous versions would simply say "I don't understand
  2003.     that sentence."  Note that the parser still attempts to combine the
  2004.     verb and preposition into a single phrase; the new action happens
  2005.     only when the verb and preposition don't go together (that is, they
  2006.     haven't been defined together as a "verb =" property of a deepverb).
  2007.     For example, suppose that a line like this appears in a deepverb:
  2008.  
  2009.         verb = 'pick up'
  2010.  
  2011.     In this case, PICK UP THE BOX will use THE BOX as the direct object,
  2012.     just as in previous versions.  Only when the verb-preposition combination
  2013.     is not specifically defined in a verb will the new phrasing be used.
  2014.  
  2015.   - When no preposition is specified between the direct and indirect objects,
  2016.     the parser will now evaluate a new property, nilPrep, in the deepverb
  2017.     object.  This property should return the preposition object that should
  2018.     be used as the preposition between the objects.  Previous versions of
  2019.     TADS always looked for an object that defined the word 'to' as a
  2020.     "preposition =" property.  While 'to' is almost always the correctly
  2021.     the correct preposition to substitute in English, it's obviously the
  2022.     wrong word in other languages; furthermore, the correct word in other
  2023.     languages is sometimes a function of verb.  If no nilPrep property is
  2024.     defined for the deepverb, the parser will still use the object whose
  2025.     "preposition =" property matches the word 'to'.
  2026.  
  2027.   - The class transparentItem in adv.t has been modified so it works better
  2028.     when you define an object that inherits from both transparentItem and
  2029.     container or openable.  First, an ldesc has been added so that the
  2030.     contents of a transparentItem are listed by default with the ldesc.
  2031.     Second, the "look in" command now works on a transparentItem.  In
  2032.     addition, the openable class has been changed so that the "look in"
  2033.     command can be used when an openable is also a transparentItem, even
  2034.     when the openable is closed (because you should be able to see the
  2035.     contents of a transparentItem regardless of whether it's open or closed).
  2036.     Thanks to Ron Hale-Evans for pointing out this problem and finding the
  2037.     solution.
  2038.  
  2039.  
  2040. Please consult TADSV200.MAC (available on the High Energy BBS) for
  2041. information on earlier releases.
  2042.